const express = require('express');
const router = express.Router();
const { body, validationResult } = require('express-validator');
const rateLimit = require('express-rate-limit');
const { Confession } = require('../model/hua');
const { userModel } = require('../model/model');

// 检查用户是否已登录的中间件
const authMiddleware = async (req, res, next) => {
  try {
    // 在实际应用中，这里应该从token中获取用户ID
    const userId = req.headers['x-user-id'];
    if (!userId) {
      return res.status(401).json({ message: '请先登录' });
    }
    
    const user = await userModel.findById(userId);
    if (!user) {
      return res.status(401).json({ message: '用户不存在' });
    }
    
    req.user = user;
    next();
  } catch (error) {
    res.status(500).json({ message: '认证失败', error: error.message });
  }
};

// 检查发帖权限的中间件
const checkConfessionLimit = async (req, res, next) => {
  try {
    const user = req.user;
    const now = new Date();
    const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
    
    // 重置每日发帖计数
    if (user.lastConfessionDate && user.lastConfessionDate < today) {
      user.dailyConfessionCount = 0;
      await user.save();
    }
    
    // 检查是否是会员
    const isVip = user.vipLevel > 0 && user.vipExpires && user.vipExpires > now;
    const maxConfessions = isVip ? 10 : 5; // 会员每天10次，非会员5次
    
    if (user.dailyConfessionCount >= maxConfessions) {
      return res.status(403).json({
        message: '今日发帖次数已用完',
        needVip: !isVip
      });
    }
    
    next();
  } catch (error) {
    res.status(500).json({ message: '检查发帖权限失败', error: error.message });
  }
};

// 请求限流中间件 - 15分钟内每个IP最多10次请求
const confessionLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 10,
  message: { message: '请求过于频繁，请15分钟后再试' }
});

// 输入验证中间件
const validateConfession = [
  body('content').trim().notEmpty().withMessage('表白内容不能为空')
    .isLength({ max: 500 }).withMessage('表白内容不能超过500字')
];

const validateComment = [
  body('content').trim().notEmpty().withMessage('评论内容不能为空')
    .isLength({ max: 200 }).withMessage('评论内容不能超过200字')
];

// 获取表白列表（支持分页）
router.get('/', async (req, res) => {
  try {
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 10;
    const skip = (page - 1) * limit;

    const total = await Confession.countDocuments();
    const confessions = await Confession.find()
      .sort({ publishTime: -1 })
      .skip(skip)
      .limit(limit);

    res.json({ confessions, total, page, limit });
  } catch (error) {
    console.error('获取表白列表失败:', error);
    res.status(500).json({ message: '服务器错误，获取表白列表失败' });
  }
});

// 发布新表白
router.post('/', authMiddleware, checkConfessionLimit, confessionLimiter, validateConfession, async (req, res) => {
  try {
    // 验证请求数据
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ message: errors.array()[0].msg });
    }

    // 更新用户发帖计数
    const user = req.user;
    user.dailyConfessionCount += 1;
    user.lastConfessionDate = new Date();
    await user.save();
    
    const newConfession = new Confession({
      content: req.body.content,
      category: req.body.category || 'normal'
    });

    await newConfession.save();
    res.status(201).json(newConfession);
  } catch (error) {
    console.error('发布表白失败:', error);
    res.status(500).json({ message: '服务器错误，发布表白失败' });
  }
});

// 表白点赞
router.patch('/:id/like', async (req, res) => {
  try {
    const confession = await Confession.findById(req.params.id);
    if (!confession) {
      return res.status(404).json({ message: '表白内容不存在' });
    }

    confession.likeCount += 1;
    await confession.save();
    res.json({ message: '点赞成功', likeCount: confession.likeCount });
  } catch (error) {
    console.error('点赞失败:', error);
    res.status(500).json({ message: '服务器错误，点赞失败' });
  }
});

// 表白投票
router.post('/:id/vote', authMiddleware, async (req, res) => {
  try {
    const { id } = req.params;
    const user = req.user;
    
    // 检查用户是否有投票券
    if (user.voteTickets <= 0) {
      return res.status(403).json({
        message: '投票券不足，请购买投票券',
        needVoteTicket: true
      });
    }
    
    // 检查表白是否存在
    const confession = await Confession.findById(id);
    if (!confession) {
      return res.status(404).json({ message: '表白内容不存在' });
    }
    
    // 更新投票数
    confession.voteCount += 1;
    await confession.save();
    
    // 减少用户投票券
    user.voteTickets -= 1;
    await user.save();
    
    res.json({
      message: '投票成功',
      voteCount: confession.voteCount,
      remainingTickets: user.voteTickets
    });
  } catch (error) {
    console.error('投票失败:', error);
    res.status(500).json({ message: '服务器错误，投票失败' });
  }
});

// 获取校花校草榜单
router.get('/rankings', async (req, res) => {
  try {
    const { category, page = 1, limit = 10 } = req.query;
    
    if (!category || !['校花', '校草'].includes(category)) {
      return res.status(400).json({ message: '请提供有效的分类（校花/校草）' });
    }
    
    const skip = (page - 1) * limit;
    
    const total = await Confession.countDocuments({ category });
    const rankings = await Confession.find({ category })
      .sort({ voteCount: -1 })
      .skip(skip)
      .limit(limit);
    
    res.json({
      rankings,
      total,
      page: parseInt(page),
      limit: parseInt(limit)
    });
  } catch (error) {
    console.error('获取榜单失败:', error);
    res.status(500).json({ message: '服务器错误，获取榜单失败' });
  }
});

// 添加评论
router.post('/:id/comment', validateComment, async (req, res) => {
  try {
    // 验证请求数据
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ message: errors.array()[0].msg });
    }

    const confession = await Confession.findById(req.params.id);
    if (!confession) {
      return res.status(404).json({ message: '表白内容不存在' });
    }

    confession.comments.push({
      content: req.body.content
    });

    await confession.save();
    res.status(201).json({ message: '评论成功', comments: confession.comments });
  } catch (error) {
    console.error('添加评论失败:', error);
    res.status(500).json({ message: '服务器错误，添加评论失败' });
  }
});

module.exports = router;